#include "pwm.h"

/*
功能：设置并启动PWM
参数：
    fre-频率，最大6250Hz
    duty-占空比，单位是1%，超过100%视为100%
返回：无
备注：duty为0时直接重置定时器
*/
uint8_t SetPWM(uint32_t fre, uint8_t duty)
{
    /* TIM PWM output config array*/
    TIM_PwmChannelConfig_t cPwmChConfig[1] = 
    {
        [0] = 
        {
            TIM_CHANNEL_0, 
            TIM_PWM_HIGH_TRUE_PULSE, 
            TIM_POL_HIGH, 
            (PWM_MAX_COUNTER * PWM_DUTY / 100), 
            DISABLE, 
            ENABLE
        }, 
    };
    
    /* TIM PWM output Config*/
    TIM_PwmConfig_t cPwmConfig =
    {
        sizeof(cPwmChConfig)/sizeof(cPwmChConfig[0]), /*channel number*/
        0, /*counter init value*/
        PWM_MAX_COUNTER, /*counter max value*/
        cPwmChConfig /*channel config pointer*/
    };
    
    /*TIM reload config*/
    TIM_ReloadConfig_t reloadConfig =
    {
        TIM_RELOAD_FULL_CYCLE,
        0,
        0,
        NULL
    };
    /*TIM sync config for update ccv*/
    TIM_PwmSyncConfig_t syncConfig = 
    {
        TIM_UPDATE_PWM_SYN,
        TIM_UPDATE_PWM_SYN, 
        DISABLE,
        ENABLE,
        &reloadConfig
    };    
    
    if(duty)
    {
        cPwmConfig.maxCounterVal = 625000/fre;
        cPwmConfig.pwmChConfig->compareValue = (duty >= 100) ? (cPwmConfig.maxCounterVal + 1) : (cPwmConfig.maxCounterVal*duty/100.0);

        /*TIM module enable*/
        SYSCTRL_ResetModule(SYSCTRL_TIM0);
        SYSCTRL_EnableModule(SYSCTRL_TIM0);
        /* set up-counting mode */
        TIM_CountingModeConfig(PWM_TIM_ID, TIM_COUNTING_UP); 
        /* pair0 output enable */
        TIM_ChannelOutputEnable(PWM_TIM_ID, TIM_CHANNEL_0);    
        /* output complementary init*/
        TIM_OutputEdgeAlignedPwmConfig(PWM_TIM_ID, &cPwmConfig);
        /* reload config*/
        TIM_SyncConfig(PWM_TIM_ID, &syncConfig);  
        /*start TIM PWM*/
        TIM_StartCounter(PWM_TIM_ID, TIM_CLK_SOURCE_SYSTEM, TIM_CLK_DIVIDE_64);
    }
    else
    {
        SYSCTRL_ResetModule(SYSCTRL_TIM0);
    }

    return 0;
}

/*
功能：对PWM的定时器和时钟进行初始化
参数：无
返回：无
备注：
*/
void PWM_Init(void)
{    
    /* enable PORTB module*/
    CLK_ModuleSrc(CLK_PORTA, CLK_SRC_OSC40M);
    SYSCTRL_EnableModule(SYSCTRL_PORTA);

    /* enable GPIO module*/
    SYSCTRL_EnableModule(SYSCTRL_GPIO);
    
    /* set pin as GPIO*/
    PORT_PinmuxConfig(PWM_OUT1_GPIO, PWM_OUT1_PIN, PTA2_TIM0_CH0);

    /*TIM clock source select*/
    CLK_ModuleSrc(CLK_TIM0, CLK_SRC_OSC40M);
    CLK_SetClkDivider(CLK_TIM0, CLK_DIV_1);
}